import 'dart:convert';
import 'dart:developer';

import 'package:bot_toast/bot_toast.dart';
import 'package:dio/dio.dart';
import 'package:shopping_group/base/base_constant.dart';
import 'package:shopping_group/event/event.dart';
import 'package:shopping_group/utils/log_util.dart';
import 'package:shopping_group/utils/route_util.dart';
import 'dart:js' as js;
import 'apis/apis.dart';

class BaseUrl {
  // 配置默认请求地址
  static const String BASE_URL = Apis.BASE_URL;
}

class HttpUtilAll {
//  static CancelToken cancelToken = new CancelToken();
  static Map<String, CancelToken> _cancelTokens =
      new Map<String, CancelToken>();

  static void get(String url,
      {Map<String, dynamic> data,
      Map<String, dynamic> headers,
      Function success,
      Function error}) async {
    // 数据拼接
    if (data != null && data.isNotEmpty) {
      LogUtil.e(data.toString(), tag: 'url get data....');
      StringBuffer options = new StringBuffer('?');
      data.forEach((key, value) {
        options.write('$key=$value&');
      });

      String optionsStr = options.toString();
      optionsStr = optionsStr.substring(0, optionsStr.length - 1);
      url += optionsStr;
      LogUtil.e(url, tag: 'url get....');
    }

    // 发送get请求
    await _sendRequest(url, 'get', success, headers: headers, error: error);
  }

  static void post(String url,
      {dynamic data,
      Map<String, dynamic> headers,
      Function success,
      Function error,
      CancelToken cancelToken}) async {
    // 发送post请求
    _sendRequest(url, 'post', success,
        data: data,
        headers: headers,
        error: error,
        cancelToken: null == cancelToken ? CancelToken() : cancelToken);
  }

  // 请求处理
  static Future _sendRequest(String url, String method, Function success,
      {dynamic data,
      Map<String, dynamic> headers,
      Function error,
      CancelToken cancelToken}) async {
    String _code;
    String _msg;
    // bool _success;
    // var _backData;

    // 检测请求地址是否是完整地址
    if (!url.startsWith('http')) {
      // if (url.contains('oauth2')) {
      //   url = Apis.WEIXIN_GZH_URL + url;
      // } else {
      url = BaseUrl.BASE_URL + url;
      // }
    }
    // 配置dio请求信息
    Response response;
    var resCallbackMap;
    try {
      dynamic dataMap;
      if (data is Map<String, dynamic>) {
        dataMap = data;
      } else if (data is List) {
        dataMap = data;
      } else if (data is FormData) {
        dataMap = data;
      }

      Map<String, dynamic> headersMap = headers == null ? new Map() : headers;
      // if (BaseConstant.token.length > 0) {
      // js.context.callMethod('flutterAlert', [BaseConstant.token]);
      headersMap['token'] = BaseConstant.token;
      headersMap['version'] = BaseConstant.VERSION;
      // }

      Dio dio = new Dio();
      dio.options.connectTimeout = 60000; // 服务器链接超时，毫秒
      dio.options.receiveTimeout = 10000; // 响应流上前后两次接受到数据的间隔，毫秒
      dio.options.headers
          .addAll(headersMap); // 添加headers,如需设置统一的headers信息也可在此添加
      dio.options.receiveDataWhenStatusError = true;

      if (method == 'get') {
        response = await dio.get(url, cancelToken: cancelToken);
      } else {
        response = await dio.post(url, data: dataMap, cancelToken: cancelToken);
      }
      //LogUtil.e(url, tag: 'urlR dataMap...........');

      LogUtil.e(response.data.toString(), tag: 'resCallbackMap...........');
      // 返回结果处理
      // if (response.data is ErrorEntity) {
      //   resCallbackMap = ErrorEntity.fromJson(response.data);
      //   _code = resCallbackMap['errcode'];-+
      //   _msg = resCallbackMap['errmsg'];
      // } else {
      resCallbackMap = response.data['data'];
      // }
      log("data == ${data}");
      log("url == ${url}");
      log("result== ${jsonEncode(response.data)}");

      // LogUtil.e(response.data.toString() + ':' + url, tag: 'resCallbackMap...........');

      if (response.statusCode != 200) {
        BotToast.showText(text: '系统繁忙');
        return;
      }
      _code = response.data['returnCode'];
      _msg = response.data['returnMsg'];
      if (null == _code || '200' != _code) {
        if ('5001' == _code) {
          eventBus.fire(RsetLoginEvent());
        } else {
          _handError(error, _msg);
        }
        return;
      }
      // _backData = resCallbackMap['data'];

      // _success = resCallbackMap['success'];

      if (null != resCallbackMap) {
        // if (null != _backData) {
        //   success(_backData);
        // } else {
        //   success(Map<String, dynamic>());
        // }
        // for (var i = 0; i < 200000; i++) {
        //   BaseConstant.videoUrlList.add(resCallbackMap);
        // }
        success(resCallbackMap);
      } else {
        // String errorMsg = resCallbackMap['returnMsg'];
        String returnCode = resCallbackMap['returnMsg'];
        _handError(error, returnCode);
      }
    } on DioError catch (e) {
      // if (response.request.data is Map) {
      //   _code = resCallbackMap['errcode'];
      //   _msg = resCallbackMap['errmsg'];
      // }
      formatError(e);
    }
  }

  /*
   * error统一处理
   */
  static void formatError(DioError e) {
    BotToast.closeAllLoading();
    if (e.type == DioErrorType.CONNECT_TIMEOUT) {
      // It occurs when url is opened timeout.
      BotToast.showText(text: '连接超时');
    } else if (e.type == DioErrorType.SEND_TIMEOUT) {
      // It occurs when url is sent timeout.
      BotToast.showText(text: '请求超时');
    } else if (e.type == DioErrorType.RECEIVE_TIMEOUT) {
      //It occurs when receiving timeout
      BotToast.showText(text: '响应超时');
    } else if (e.type == DioErrorType.RESPONSE) {
      // When the server response, but with a incorrect status, such as 404, 503...
      // int _code;
      String _msg;
      if (e.response.data is Map) {
        LogUtil.e(e.response.data.toString(),
            tag: 'resCallbackMap e.response.data...........');
        // _code = e.response.data['errcode'];
        // if (999999 == _code) {
        //   RouteUtil.goView(PageConstance.LOGIN_PAGE);
        // }
        _msg = e.response.data['errmsg'];
        if (_msg != null) {
          BotToast.showText(text: _msg ?? "");
        }
      }
    } else if (e.type == DioErrorType.CANCEL) {
      // When the request is cancelled, dio will throw a error with this type.
      BotToast.showText(text: '请求取消');
    } else {
      //DEFAULT Default error type, Some other Error. In this case, you can read the DioError.error if it is not null.
      BotToast.showText(text: '未知错误');
    }
  }

  // 返回错误信息
  static Future _handError(Function errorCallback, String errorMsg) async {
    if (errorCallback != null) {
      errorCallback(errorMsg);
    }
  }

  ///取消请求
  static void cancelTokens(String tag) {
    if (_cancelTokens.containsKey(tag)) {
      if (!_cancelTokens[tag].isCancelled) {
        _cancelTokens[tag].cancel();
      }
      _cancelTokens.remove(tag);
    }
  }
}
